home *** CD-ROM | disk | FTP | other *** search
- # SpecTcl, by S. A. Uhler
- # Copyright (c) 1994-1995 Sun Microsystems, Inc.
- #
- # See the file "license.txt" for information on usage and redistribution
- # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- #
- # file for button bindings (This is being re-written as we speak!
-
- # <prefix>_down: The button went down
- # <prefix>_start_sweep We started a sweep
- # <prefix>_sweep We are sweeping
- # <prefix>_end_sweep We ended the sweep (button up)
- # <prefix>_up button up - no sweep
-
- # arguments:
- # win: The window the button was clicked on (%W)
- # x,y: The absolute mouse coordinates (%X %Y)
-
- ########################################################
- # procedures for managing hits on widget palette
-
- proc palette_down {win x y} {
- global _Message
- set _Message "Drag to create a new [$win cget -text]"
- $win configure -relief sunken
- unselect_widget
- }
-
- # To autoscroll a canvas, we schedule scrolling using after.
- # Cancel contains the next scheduled auto-scroll command.
- # to stop auto scrolling, cancel "Cancel"
-
- set Cancel 0
- proc palette_start_sweep {win x y} {
- global Type In_view Where Row Col
- set Where ""
- set Type [$win cget -text]
- set In_view 0
- set Row ""; set Col ""
- unselect_widget
- current_frame .can.f
- label .label -bd 2 -relief ridge -text $Type
- }
-
- # track the cursor over the canvas, keep track of its position
- # The optional "repeat" argument is used for auto-scrolling
-
- set Status "" ;# keep track of the row/col we're sitting on
- proc palette_sweep {win x y {repeat 0}} {
- global P Current Frames Where Before
- global Root_x Root_y Cancel Row Col
- global _Message
- global Status
-
- # make sure the widget is in view
-
- if {$repeat == 0} {
- after cancel $Cancel
- }
- if {[keep_in_view .can $x $y]} {
- place .label -anchor c -x [expr $x - $Root_x] -y [expr $y - $Root_y]
- } else {
- set Cancel [after $P(scroll_delay) "palette_sweep $win $x $y 1"]
- }
-
- # where on the canvas are we?
-
- set Before $Where
- set row $Row; set col $Col
- set Where [find_slot $Current(frame) $x $y Row Col]
- if {$Where == $Before && $Row == $row && $Col == $col} {
- return
- }
- choose_look $win $Where
-
- switch -glob $Where {
- Cr { # on a row grid line
- arrow_unhighlight row
- }
- Cc { # on a column grid line
- arrow_unhighlight column
- }
- Crc { # on both row and column grid line
- arrow_unhighlight column
- arrow_unhighlight row
- }
- C* { # in a slot
- set on [blt_table slaves $Current(frame) -row $Row -column $Col]
- if {$on != ""} {
- choose_look $win occupied
- if {[info exists Frames($on)]} {
- dputs "Entering sub-frame $on"
- current_frame [find_grid $x $y "" $on]
- }
- set Status "Occupied"
- set color red
- } else {
- set Status ""
- set color green
- }
- arrow_highlight column $Current(frame) $Col $color
- arrow_highlight row $Current(frame) $Row $color
- set _Message "row: [expr $Row/2] col: [expr $Col/2] $Status"
- }
- default { # outside the grid
- dputs left frame $Current(frame)
- current_frame [find_grid $x $y]
- }
- }
- }
-
- # Create a new widget and plunk it down
-
- proc palette_end_sweep {win x y} {
- global Next_widget Type
- global Current
- global Cancel _Message
- global Row Col Widgets
- global Widget_data
- global In_view Where
- upvar #0 geom:$Current(frame) data
-
- # create the widget
-
- choose_look $win reset
- destroy .label
- if {$In_view == 0} {
- return
- }
- check_table $Current(frame) $Where Row Col
- set on [blt_table slaves $Current(frame) -row $Row -column $Col]
- if {$on != ""} {
- set _Message "$Row,$Col is occupied, [choose_insult]!"
- } else {
- undo_mark
- set template .sample_$Type
- set new .can.f.$Type#[incr Next_widget($Type)]
- clone_widget $template $new
- if {$Type == "frame"} {
- bindtags $new "First frame widget [bindtags $new]"
- } else {
- bindtags $new "First widget [bindtags $new]"
- }
- set_master $new $Current(frame)
- table_enter $Current(frame) $new $Row $Col
-
- widget_extract $new
- set _Message "Created new $Type at $Row,$Col"
- set name [winfo name $new]
- set Widgets($name) 1
- undo_log create_widget $name
-
- # Each widget class (potentially) has its own special case
- # code to configure the class. Run it here, as a filter
-
- if {[info exists Widget_data(filter:[winfo class $new])]} {
- eval $Widget_data(filter:[winfo class $new]) $new
- }
-
- outline_create $name
- unselect_widget
- select_widget $new
-
- # testing
-
- if {$Type == "frame"} {
- dputs "Inserting subgrid tag for $new"
- insert_tag $new sub_grid
- }
- }
-
- # destroy the temporary one
-
- arrow_unhighlight row
- arrow_unhighlight column
- after cancel $Cancel
- set Type ""
- }
-
- set Current(sample) "" ;# this should be elsewhere
- proc palette_up {win x y} {
- return ;# use double click only!
- }
-
- ####### AUX procedures used by bindings
-
- # scroll canvas to keep in view
- # x and y are root coords
- # Make sure we don't scroll before the widget is in bounds
-
- proc keep_in_view {win x y} {
- global In_view
- set in_bounds 0
- if {$x < [winfo rootx $win]} {
- if {$In_view} {
- $win xview scroll -1 units
- ${win}_column xview scroll -1 units
- }
- } elseif {$y < [winfo rooty $win]} {
- $win yview scroll -1 units
- ${win}_row yview scroll -1 units
- } elseif {$x > [winfo rootx $win] + [winfo width $win]} {
- $win xview scroll 1 units
- ${win}_column xview scroll 1 units
- } elseif {$y > [winfo rooty $win] + [winfo height $win]} {
- $win yview scroll 1 units
- ${win}_row yview scroll 1 units
- } else {
- set In_view 1
- set in_bounds 1
- }
- if {$In_view && !$in_bounds} {
- return 0
- } else {
- return 1
- }
- }
-
- # get the row and column position
- # win: table master
- # x,y: Root x and y coords
- # row,col: get filled in if True
- # result: code indicating where it is
- # position relative to grid: nw n ne e se s sw w
- # where in grid: r c rc (row, column, row&column)
- # "" on a grid slot
-
- proc find_slot {win x y set_row set_col} {
- upvar $set_row row $set_col col
- set result ""
- incr x -[winfo rootx $win.@0]
- incr y -[winfo rooty $win.@0]
- set row [blt_table row $win location $y]
- set col [blt_table column $win location $x]
-
- if {$y < 0} {
- append result n
- } elseif {$row >= [blt_table row $win dimension]} {
- append result s
- }
- if {$x < 0} {
- append result w
- } elseif {$col >= [blt_table column $win dimension]} {
- append result e
- }
-
- if {$result != ""} {
- dputs $win $x,$y $row,$col $result
- return $result
- }
- set result C
-
- if {$row&1} {
- append result r
- }
- if {$col&1} {
- append result c
- }
- dputs $win $x,$y $row,$col $result
- return $result
- }
-
- ########################################################3
- # procedures for managing hits on widgets
- # these should be combined with the palette routines!!
-
- proc widget_down {win x y} {
- global _Message Current
- if {$win == $Current(widget)} {
- set _Message "Double click to activate option sheet"
- } else {
- set _Message "selecting [winfo name $win]"
- }
- }
-
- # take 2 - sweep a label, not the entire widget
-
- proc widget_start_sweep {win x y} {
- global In_view Where Row Col
- upvar #0 [winfo name $win] data
- set Where ""
- set In_view 0
- set Row $data(row)
- set Col $data(column)
- unselect_widget
- current_frame .can.f[find_master $win]
- label .label -bd 2 -relief raised -text [widget_describe $win]
- }
-
- proc widget_sweep {win x y {repeat 0}} {
- palette_sweep $win $x $y $repeat
- }
-
- proc widget_end_sweep {win x y} {
- global Shift Cancel _Message Current
- global Row Col Where
- upvar #0 geom:$Current(frame) data
- after cancel $Cancel
-
- # move or copy it!
-
- destroy .label
- choose_look $win reset
- check_table $Current(frame) $Where Row Col
- unselect_widget
- set on [blt_table slaves $Current(frame) -row $Row -column $Col]
- if {$on == ""} {
- if {$Shift} {
- undo_mark
- set win [copy_widget $Current(frame) $win $Row,$Col]
- } else {
- move_widget $Current(frame) $win $Row $Col
- }
- set_master $win $Current(frame)
- select_widget $win
-
- # Its confusing without this
- blt_table configure $win -rowspan 1 -columnspan 1
- set rowspan 1; set columnspan 1; set row $Row; set column $Col
-
- foreach i {row column columnspan rowspan} {
- sync_form $i [set $i]
- }
- }
- arrow_unhighlight row
- arrow_unhighlight column
- }
-
- # copy a widget to row,col
- # return widget name. Assumes new widget is a sibling of the old one
- # master: The frame to manage the copy in
- # win: The widget to copy
- # position: row,col: Where to put it (if moved)
-
- # BROKEN for copying frames!
-
- proc copy_widget {master win {position ""}} {
- global Next_widget Widgets Frames P
- dputs $master $win $position
-
- # name and clone the widget parameters
-
- set class [winfo class $win]
- set type [string tolower $class]
- set name $type#[incr Next_widget($type)]
- set path .can.f.$name
- clone_widget $win $path
- upvar #0 $name dst [winfo name $win] src
- array set dst [array get src]
-
- # change the parameters
-
- set geom [blt_table info $win]
- if {$position != ""} {
- set geom [lreplace $geom 0 1 $position]
- } else {
- set geom [lrange $geom 1 end ]
- }
- eval "blt_table $master $path $geom"
- if {$type == "frame"} {
- bindtags $path "First frame widget [bindtags $path]"
- } else {
- bindtags $path "First widget [bindtags $path]"
- }
- set Widgets($name) 1
- undo_log create_widget $name
- widget_extract $path $name
- outline_create $name
-
- catch {unset dst(focus)}
- set dst(item_name) $name
- set dst(pathname) $name
-
- # If this is a frame, copy all its children,
- # Then make the grid and arrows (broken, but close)
-
- if {[info exists Frames($win)]} {
- dputs "COPYING SUB FRAME $win"
- grid_size $win maxrows maxcols
- frame_create $path $maxrows $maxcols
- foreach child [blt_table slaves $win] {
- dputs "Copying $child for $win"
- if {[info exists Widgets([winfo name $child])]} {
- set new [copy_widget $path $child]
- set_master $new $path
- after idle "outline_trace [winfo name $new]"
- }
- }
- arrow_update .can $path
- }
- return $path
-
- # need to do sub-frame processing here (Broken!)
-
- if {[info exists dst(panel)]} {
- read_file $dst(panel) $path
- }
- }
-
- # move a widget to row,col and update form entries
- # table: Where to move the table to
- # win: The name of the window to move
- # row,column: Where in the table to put it
-
- proc move_widget {table win row column} {
- global Current
- set Current(dirty) 1
- set info [blt_table info $win]
- blt_table forget $win
- eval "blt_table $table [lreplace $info 1 1 $row,$column]"
-
- # this still isn't quite right
- if {[winfo class $win] != "Frame"} {
- raise $win
- }
- }
-
- # make the proper widget selected
- # 1 if frame and selected, de-select and select row/col instead
- # 2 if "parent" is current frame, select widget
- # 3 select parent who is a child of the current frame
-
- set Current(widget) "" ;# name of "current widget(s)?"
- set Current(text) "" ;# the text or label of the current widget
- set Current(form) "" ;# the widget with an active option sheet
- proc widget_up {win x y {focus ""}} {
- global _Message Current
- set array_name [winfo name $win]
- upvar #0 $array_name data
- if {$focus != ""} {set data(focus) $focus}
-
- # Clicked in frame, select row/col
-
- if {$win == $Current(widget) && [regexp {^.can.f.frame#} $win]} {
- dputs "selecting row/col in frame ($x,$y)"
- current_frame $win
- select_rowcol [expr $x - [winfo rootx $win]] [expr $y - [winfo rooty $win]]
- return
- }
-
- if {$win != $Current(widget)} {
- unselect_widget
- select_widget $win
- }
- }
-
- # make the named widget "selected"
- # as a side effect, make its "master" current
-
- proc select_widget {win} {
- global Current P
- window_highlight $win
- set name [winfo name $win]
-
- set master .can.f[find_master $win]
- dputs $win in $master (current is $Current(frame))
- table_setup $master ;# testing
- set Current(widget) $win
- current_frame $master
- if {![winfo exists ${win}_outline]} { ;# we need to undo this!
- outline_activate $name
- outline_update $master
- }
- add_resize_handles $master.${name}_outline 3 1
-
- focus .entry
- sync_all {}
- arrow_unhighlight row
- arrow_unhighlight column
- }
-
- # If we selected a spot that is "out of bounds", then extend the table,
- # and make sure the spot IS in bounds
-
- proc check_table {table where myrow mycol} {
- upvar $myrow row $mycol col
- set add 0
-
- # check front of table
- dputs $table at $where $row,$col
-
- if {$row <= 1} {
- table_insert $table row [set row 2]
- grid_process $table row 1
- incr add
- }
- if {$col <= 1} {
- table_insert $table column [set col 2]
- grid_process $table column 1
- incr add
- }
-
- # check on grid lines
-
- if {$row&1} {
- table_insert $table row [incr row]
- grid_process $table row 1
- incr add
- }
- if {$col&1} {
- table_insert $table column [incr col]
- grid_process $table column 1
- incr add
- }
-
- # check ends of table
-
- if {[string match *e $where]} {
- resize_insert $table column 999
- grid_process $table column 1
- incr add
- }
- if {[string match s* $where]} {
- resize_insert $table row 999
- grid_process $table row 1
- incr add
- }
- return $add
- }
-
- # map grid locations into cursor styles
-
- array set Choose_cursor {
- Cr sb_v_double_arrow Cc sb_h_double_arrow Crc cross
- s sb_down_arrow n sb_up_arrow
- e sb_right_arrow w sb_left_arrow
- nw top_left_corner ne top_right_corner
- sw bottom_left_corner se bottom_right_corner
- inside dot
- occupied X_cursor
- reset {}
- }
-
- # choose a "look" for the window based upon where we are
- # This version picks a new cursor, but anything that works...
-
- proc choose_look {win where} {
- global Choose_cursor
- dputs $win $where
- if {[info exists Choose_cursor($where)]} {
- set cursor $Choose_cursor($where)
- } else {
- set cursor $Choose_cursor(inside)
- }
- $win configure -cursor $cursor
- }
-